package com.jiantong.web.open.app.trace;

import com.jiantong.user.enums.BreedFactoryIsScale;
import com.jiantong.user.model.BreedFactory;
import com.jiantong.user.model.User;
import com.jiantong.user.service.BreedFactoryReadService;
import com.jiantong.user.service.UserReadService;
import com.jiantong.web.core.enums.ExceptionCode;
import com.jiantong.work.enums.AnimalMarkStatus;
import com.jiantong.work.model.*;
import com.jiantong.work.service.*;
import com.jiantong.work.trace.TraceInfo;
import com.jiantong.work.trace.TraceQuarantineCertNumber;
import io.terminus.boot.rpc.common.annotation.RpcConsumer;
import io.terminus.common.model.Response;
import io.terminus.pampas.openplatform.annotations.OpenBean;
import io.terminus.pampas.openplatform.annotations.OpenMethod;
import io.terminus.pampas.openplatform.exceptions.OPClientException;
import io.terminus.pampas.openplatform.exceptions.OPServerException;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Strings;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.List;

/**
 * Created by mz on 27/7/17.
 *
 */
@Slf4j
@OpenBean
public class Tracings {

    @RpcConsumer
    private UserReadService userReadService;

    @RpcConsumer
    private AnimalMarkReadService animalMarkReadService;

    @RpcConsumer
    private BreedFactoryReadService breedFactoryReadService;

    @RpcConsumer
    private ImmunizationSubRecordReadService immunizationSubRecordReadService;

    @RpcConsumer
    private ImmunizationRecordReadService immunizationRecordReadService;

    @RpcConsumer
    private RetailBreedRecordReadService retailBreedRecordReadService;

    @RpcConsumer
    private RetailImmunizationRecordReadService retailImmunizationRecordReadService;

    @RpcConsumer
    private RetailImmunizationSubRecordReadService retailImmunizationSubRecordReadService;

    @RpcConsumer
    private BreedReportReadService breedReportReadService;

    @RpcConsumer
    private BreedReportSurveyRecordReadService breedReportSurveyRecordReadService;

    @RpcConsumer
    private QuarantineCenterHarmlessReadService quarantineCenterHarmlessReadService;

    @RpcConsumer
    private HarmlessReadService harmlessReadService;


    /**
     * 根据耳标号
     * @param markNumber 耳标号
     * @param markType 动物类型
     * @return TraceInfo
     */
    @OpenMethod(
            key = "trace.by.mark.number",
            paramNames = {"markNumber","markType"},
            httpMethods = RequestMethod.GET
    )
    public TraceInfo traceByMarkNumber(String markNumber,Integer markType){
        if(Strings.isNullOrEmpty(markNumber)){
            log.error("mark number should be not null");
            throw new OPClientException(ExceptionCode.PARAMETER_NOT_EXIST.value(),
                    "mark number should be not null");
        }

        if(markNumber.length() != 15 && markType == null){
            log.error("mark number length is error");
            throw new OPServerException(ExceptionCode.PARAMETER_IS_INVALID.value(),
                    "mark number length is error");
        }
        TraceInfo traceInfo = new TraceInfo();//溯源的对象

        //根据耳标的详细信息
        Response<AnimalMark> animalMarkResponse = animalMarkReadService.findByMarkNumber(markNumber,markType);
        if(!animalMarkResponse.isSuccess()){
            log.error("failed to find animal mark case = {}",animalMarkResponse.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),animalMarkResponse.getError());
        }
        AnimalMark animalMark = animalMarkResponse.getResult();

        Response<BreedReport> breedReportResponse = breedReportReadService.findByMarkNumber(markType,markNumber);
        if(!breedReportResponse.isSuccess()){
            log.error("failed to find breed report case = {}",breedReportResponse.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),breedReportResponse.getError());
        }

        BreedReport breedReport = breedReportResponse.getResult();
        if(breedReport != null){
            Response<BreedReportSurveyRecord> reportSurveyRecordResponse = breedReportSurveyRecordReadService.findByReportId(breedReport.getId());
            if(!reportSurveyRecordResponse.isSuccess()){
                log.error("failed to find breed report gov case = {}",reportSurveyRecordResponse.getError());
                throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),reportSurveyRecordResponse.getError());
            }
            if(reportSurveyRecordResponse.getResult() != null){
                traceInfo.setBreedReport(breedReport);
                traceInfo.setBreedReportSurveyRecord(reportSurveyRecordResponse.getResult());
            }
            Response<Harmless> harmlessResponse = harmlessReadService.findHarmlessByMarkNumberAndReportId(animalMark.getMarkNumber(),breedReport.getId());
            if(!harmlessResponse.isSuccess()){
                log.error("failed to find harmless , case = {}",harmlessResponse.getError());
                throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),harmlessResponse.getError());
            }
            if(harmlessResponse.getResult() != null){
                traceInfo.setHarmless(harmlessResponse.getResult());
            }
        }

        if(animalMark == null){
            log.error("animal mark is not in system");
            //返回错误信息

            traceInfo.setSomethingInfo("该耳标号尚未入库");
            return traceInfo;
        }

        //放入耳标信息
        traceInfo.setAnimalMark(animalMark);
        Integer markStatus = animalMark.getStatus();//耳标的状态
        Long breedFactoryId = animalMark.getBreedFactoryId();//所属养殖场

        //根据耳标所属养殖场查询养殖场的详细信息
        Response<BreedFactory> breedFactoryResponse = breedFactoryReadService.findById(breedFactoryId);
        if(!breedFactoryResponse.isSuccess()){
            log.error("failed to find breed factory id case = {}",breedFactoryResponse.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),breedFactoryResponse.getError());
        }

        BreedFactory breedFactory = breedFactoryResponse.getResult();//养殖场信息

        Response<User> userResponse = userReadService.findById(breedFactory.getUserId());
        if(!userResponse.isSuccess()){
            log.error("failed to find user",userResponse.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),userResponse.getError());
        }

        traceInfo.setUser(userResponse.getResult());
        //放入养殖场信息
        traceInfo.setBreedFactory(breedFactory);

        if(markStatus == AnimalMarkStatus.DEPOSITED.value()){
            //返回耳标信息和养殖场信息
            traceInfo.setSomethingInfo("该耳标号已损毁");
            return traceInfo;
        }

        Integer isScale = breedFactory.getIsScale();//是否是规模场

        if(isScale == BreedFactoryIsScale.SCALE.value()){//若果是规模场
            //根据耳标模糊查询免疫记录详细信息
            Response<ImmunizationRecord> immunizationRecordResponse =
                    immunizationRecordReadService.findByEarNumber(breedFactoryId,animalMark.getMarkNumber());
            if(!immunizationRecordResponse.isSuccess()){
                log.error("failed to find ImmunizationRecord by ear number , case = {}",
                        immunizationRecordResponse.getError());
                throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),
                        immunizationRecordResponse.getError());
            }
            //拿到免疫记录主表的信息
            ImmunizationRecord immunizationRecord = immunizationRecordResponse.getResult();
            if(immunizationRecord == null){
                traceInfo.setSomethingInfo("该耳标号尚未佩标");
                return traceInfo;
            }
            Long vaccineId = immunizationRecord.getId();

            //放入免疫记录的主表信息
            traceInfo.setImmunizationRecord(immunizationRecord);

            Response<List<ImmunizationSubRecord>> listResponse =
                    immunizationSubRecordReadService.selectList(vaccineId);

            if(!listResponse.isSuccess()){
                log.error("failed to select list ImmunizationSubRecord by vaccineId , case = {}",
                        listResponse.getError());
                throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),
                        listResponse.getError());
            }
            //拿到免疫记录字表的信息list
            List<ImmunizationSubRecord> immunizationSubRecordList = listResponse.getResult();
            //放入免疫记录的信息
            traceInfo.setImmunizationSubRecords(immunizationSubRecordList);
            traceInfo.setIsScale(isScale);
            //根据判断返回耳标信息、养殖场信息、免疫记录信息
            return traceInfo;
        }

        Response<RetailImmunizationRecord> recordResponse = retailImmunizationRecordReadService.findByEarNumber(breedFactoryId,markNumber);
        if(!recordResponse.isSuccess()){
            log.error("failed to find by mark number , case = {}",recordResponse.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),recordResponse.getError());
        }
        traceInfo.setRetailImmunizationRecord(recordResponse.getResult());

        if(recordResponse.getResult() != null){
            Response<List<RetailImmunizationSubRecord>> response = retailImmunizationSubRecordReadService.queryListByVaccineId(recordResponse.getResult().getId());
            if(!response.isSuccess()){
                log.error("failed to find sub retail immunization record , case = {}",response.getError());
                throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),response.getError());
            }
            traceInfo.setRetailImmunizationSubRecords(response.getResult());
        }
        traceInfo.setIsScale(isScale);
        return traceInfo;
    }

    @OpenMethod(
            key = "trace.by.quarantine.cert.number",
            paramNames = {"quarantineCertNumber"},
            httpMethods = RequestMethod.GET
    )
    public TraceQuarantineCertNumber traceQuarantineCertNumber(String quarantineCertNumber){
        if(Strings.isNullOrEmpty(quarantineCertNumber)){
            log.error("quarantineCertNumber should be not null");
            throw new OPClientException(ExceptionCode.PARAMETER_NOT_EXIST.value(),"quarantineCertNumber should be not null");
        }

        Response<BreedReportSurveyRecord> breedReportSurveyRecordResponse = breedReportSurveyRecordReadService.findByQuarantineCertNumber(quarantineCertNumber);
        if(!breedReportSurveyRecordResponse.isSuccess()){
            log.error("failed to find breedReportSurveyRecord , case = {}",breedReportSurveyRecordResponse.getError());
            throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),breedReportSurveyRecordResponse.getError());
        }

        BreedReportSurveyRecord breedReportSurveyRecord = breedReportSurveyRecordResponse.getResult();

        if(breedReportSurveyRecord != null){
            Response<BreedReport> breedReportResponse = breedReportReadService.findById(breedReportSurveyRecord.getReportId());
            if(!breedReportResponse.isSuccess()){
                log.error("failed to find breedReport , case = {}",breedReportResponse.getError());
                throw new OPServerException(ExceptionCode.DATA_NOT_FOUND.value(),breedReportResponse.getError());
            }
            BreedReport breedReport = breedReportResponse.getResult();

            if(breedReport != null){
                TraceQuarantineCertNumber traceQuarantineCertNumber = new TraceQuarantineCertNumber();
                traceQuarantineCertNumber.setBreedReport(breedReport);
                traceQuarantineCertNumber.setBreedReportSurveyRecord(breedReportSurveyRecord);

                return traceQuarantineCertNumber;
            }
        }

        return new TraceQuarantineCertNumber();
    }
}
